More work on Domain Creation Wizzard.
Works well
from xen.sv.util import *
from xen.sv.GenTabbed import PreTab
-from xen.xm.create import make_config
+from xen.xm.create import make_config, OptVals
from xen.xend.XendClient import server
def __init__( self, urlWriter ):
Sheet.__init__( self, urlWriter, "General", 0 )
- self.addControl( InputControl( 'name', 'VM Name', 'VM Name:' ) )
- self.addControl( InputControl( 'memory', '64', 'Memory (Mb):' ) )
- self.addControl( InputControl( 'cpu', '0', 'CPU:' ) )
+ self.addControl( InputControl( 'name', 'VM Name', 'VM Name:', "[\\w|\\S]+", "You must enter a name in this field" ) )
+ self.addControl( InputControl( 'memory', '64', 'Memory (Mb):', "[\\d]+", "You must enter a number in this field" ) )
+ self.addControl( InputControl( 'cpu', '0', 'CPU:', "[\\d]+", "You must enter a number in this feild" ) )
class CreatePage1( Sheet ):
def __init__( self, urlWriter ):
Sheet.__init__( self, urlWriter, "Setup Kernel Image", 1 )
- self.addControl( InputControl( 'builder', 'linux', 'Kernel Type:' ) )
- self.addControl( InputControl( 'kernel', '/boot/vmlinuz-2.4.26-xenU', 'Kernel Image:' ) )
- self.addControl( InputControl( 'extra', '', 'Kernel Command Line Parame:' ) )
+ self.addControl( ListControl( 'builder', [('linux', 'Linux'), ('netbsd', 'NetBSD')], 'Kernel Type:' ) )
+ self.addControl( FileControl( 'kernel', '/boot/vmlinuz-2.4.26-xenU', 'Kernel Image:' ) )
+ self.addControl( InputControl( 'extra', '', 'Kernel Command Line Parameters:' ) )
class CreatePage2( Sheet ):
def __init__( self, urlWriter ):
Sheet.__init__( self, urlWriter, "Setup Virtual Block Device", 2 )
- self.addControl( InputControl( 'num_vbds', '1', 'Number of VBDs:' ) )
+ self.addControl( InputControl( 'num_vbds', '1', 'Number of VBDs:', '[\\d]+', "You must enter a number in this field" ) )
class CreatePage3( Sheet ):
def __init__( self, urlWriter ):
Sheet.__init__( self, urlWriter, "Setup Virtual Block Device", 3 )
- def write_BODY( self, request ):
+ def write_BODY( self, request, err ):
+ if not self.passback: self.parseForm( request )
+
previous_values = sxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference
+
num_vbds = previous_values.get( 'num_vbds' )
for i in range( int( num_vbds ) ):
- self.addControl( InputControl( 'vbd%s_dom0' % i, '/dev/sda%i' % i, 'Device %s name:' % i ) )
- self.addControl( InputControl( 'vbd%s_domU' % i, '/dev/sda%i' % i, 'Virtualized device %s:' % i ) )
- self.addControl( InputControl( 'vbd%s_mode' % i, 'w', 'Device %s mode:' % i ) )
+ self.addControl( InputControl( 'vbd%s_dom0' % i, 'phy:sda%s' % str(i + 1), 'Device %s name:' % i ) )
+ self.addControl( InputControl( 'vbd%s_domU' % i, 'sda%s' % str(i + 1), 'Virtualized device %s:' % i ) )
+ self.addControl( ListControl( 'vbd%s_mode' % i, [('w', 'Read + Write'), ('r', 'Read Only')], 'Device %s mode:' % i ) )
self.addControl( InputControl( 'root', '/dev/sda1', 'Root device (in VM):' ) )
- Sheet.write_BODY( self, request )
+ Sheet.write_BODY( self, request, err )
class CreatePage4( Sheet ):
def __init__( self, urlWriter ):
- Sheet.__init__( self, urlWriter, "Network settings", 4 )
+ Sheet.__init__( self, urlWriter, "Network settings", 4 )
+ self.addControl( ListControl( 'dhcp', [('off', 'No'), ('dhcp', 'Yes')], 'Use DHCP:' ) )
self.addControl( InputControl( 'hostname', 'hostname', 'VM Hostname:' ) )
self.addControl( InputControl( 'ip_addr', '1.2.3.4', 'VM IP Address:' ) )
self.addControl( InputControl( 'ip_subnet', '255.255.255.0', 'VM Subnet Mask:' ) )
self.addControl( InputControl( 'ip_gateway', '1.2.3.4', 'VM Gateway:' ) )
-
+ self.addControl( InputControl( 'ip_nfs', '1.2.3.4', 'NFS Server:' ) )
+
class CreateFinish( Sheet ):
def __init__( self, urlWriter ):
Sheet.__init__( self, urlWriter, "All Done", 5 )
- def write_BODY( self, request ):
- fin_sxp = string2sxp( self.passback )
+ def write_BODY( self, request, err ):
- xend_sxp = self.translate_sxp( fin_sxp )
+ if not self.passback: self.parseForm( request )
- pt = PreTab( sxp2prettystring( xend_sxp ) )
- pt.write_BODY( request )
+ xend_sxp = self.translate_sxp( string2sxp( self.passback ) )
- server.xend_domain_create( xend_sxp )
-
+ dom_sxp = server.xend_domain_create( xend_sxp )
+
+ pt = PreTab( sxp2prettystring( dom_sxp ) )
+ pt.write_BODY( request )
+
request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback )
request.write( "<input type='hidden' name='sheet' value='%s'></p>" % self.location )
def translate_sxp( self, fin_sxp ):
fin_hash = ssxp2hash( fin_sxp )
+ def get( key ):
+ ret = fin_hash.get( key )
+ if ret:
+ return ret
+ else:
+ return ""
+
vals = OptVals()
- setattr(vals, "name", fin_hash.get( 'name' ) )
- setattr(vals, "memory", fin_hash.get( 'memory' ) )
- setattr(vals, "cpu", fin_hash.get( 'cpu' ) )
+ vals.name = get( 'name' )
+ vals.memory = get( 'memory' )
+ vals.cpu = get( 'cpu' )
- setattr(vals, "builder", fin_hash.get( 'builder' ) )
- setattr(vals, "kernel", fin_hash.get( 'kernel' ) )
- setattr(vals, "root", fin_hash.get( 'root' ) )
- setattr(vals, "extra", fin_hash.get( 'extra' ) )
+ vals.builder = get( 'builder' )
+ vals.kernel = get( 'kernel' )
+ vals.root = get( 'root' )
+ vals.extra = get( 'extra' )
+
+ #setup vbds
vbds = []
- for i in range( int( fin_hash.get( 'num_vbds' ) ) ):
- vbds.append( ( fin_hash.get('vbd%s_domU' % i ), fin_hash.get( 'vbd%s_dom0' % i ), fin_hash.get( 'vbd%s_mode' % i ) ) )
+ for i in range( int( get( 'num_vbds' ) ) ):
+ vbds.append( ( get( 'vbd%s_dom0' % i ), get('vbd%s_domU' % i ), get( 'vbd%s_mode' % i ) ) )
vals.disk = vbds
- vals.pci = []
+ #misc crap
- vals.vif = []
- vals.nics = 1
+ vals.pci = []
vals.blkif = None
vals.netif = None
vals.console = None
vals.ramdisk = None
- #todo: setup ip addr stuff
+ #setup vifs
- vals.cmdline_ip = None
+ vals.vif = []
+ vals.nics = 1
+
+ ip = get( 'ip_addr' )
+ nfs = get( 'ip_nfs' )
+ gate = get( 'ip_gateway' )
+ mask = get( 'ip_subnet' )
+ host = get( 'hostname' )
+ dhcp = get( 'dhcp' )
- return make_config( vals )
-
+ vals.cmdline_ip = "%s:%s:%s:%s:%s:eth0:%s" % (ip, nfs, gate, mask, host, dhcp)
-class OptVals:
- """Class to hold option values.
- """
- pass
\ No newline at end of file
+ return make_config( vals )
return self.write_BODY( request, head=True, long=False )
def write_BODY( self, request, head=True, long=True ):
-
- domains = server.xend_domains()
+
+ domains = map(int, server.xend_domains())
+ domains.sort()
request.write( "\n<table style='border:0px solid white' cellspacing='0' cellpadding='0' border='0' width='100%'>\n" )
def render_POST( self, request ):
self.perform( request )
- self.render_GET( request )
+ return self.render_GET( request )
def render_GET( self, request ):
self.write_TOP( request )
self.write_BODY( request )
self.write_BOTTOM( request )
- request.finish()
return ''
def write_BODY( self, request ):
from xen.sv.HTMLBase import HTMLBase
from xen.xend import sxp
-DEBUG = 1
+import re
+
+DEBUG = 0
class Wizard( HTMLBase ):
else:
currSheet = 0
- op = getVar( 'op', request )
+ sheet = self.sheets[ currSheet ]( self.urlWriter )
+
+ err = not sheet.validate( request )
+
+ if not err:
+ op = getVar( 'op', request )
- if op == 'next':
- currSheet += 1
- elif op == 'prev':
- currSheet -= 1
+ if op == 'next':
+ currSheet += 1
+ elif op == 'prev':
+ currSheet -= 1
- sheet = self.sheets[ currSheet ]( self.urlWriter )
-
- sheet.parseForm( request )
- sheet.write_BODY( request )
+ sheet = self.sheets[ currSheet ]( self.urlWriter )
+
+ if getVar( 'visited-sheet%s' % currSheet, request ):
+ sheet.write_BODY( request, err )
+ else:
+ sheet.write_BODY( request, False )
+
request.write( "</td></tr><tr><td><table width='100%' border='0' cellspacing='0' cellpadding='0'><tr>" )
request.write( "<td width='80%'></td><td width='20%' align='center'><p align='center'>" )
self.feilds = []
self.title = title
self.location = location
- self.passback = "()"
+ self.passback = None
def parseForm( self, request ):
- do_not_parse = [ 'mod', 'op', 'sheet' ]
+ do_not_parse = [ 'mod', 'op', 'sheet', 'passback' ]
passed_back = request.args
if DEBUG: print last_passback
- try:
- del passed_back[ 'passback' ]
- except:
- pass
-
for (key, value) in passed_back.items():
if key not in do_not_parse:
last_passback[ key ] = value[ len( value ) - 1 ]
if DEBUG: print self.passback
- def write_BODY( self, request ):
+ def write_BODY( self, request, err ):
+
+ if not self.passback: self.parseForm( request )
request.write( "<p>%s</p>" % self.title )
- previous_values = sxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference
+ previous_values = ssxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference
request.write( "<table width='100%' cellpadding='0' cellspacing='1' border='0'>" )
for (feild, control) in self.feilds:
control.write_Control( request, previous_values.get( feild ) )
+ if err and not control.validate( previous_values.get( feild ) ):
+ control.write_Help( request )
request.write( "</table>" )
request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback )
request.write( "<input type='hidden' name='sheet' value='%s'></p>" % self.location )
-
+ request.write( "<input type='hidden' name='visited-sheet%s' value='True'></p>" % self.location )
+
def addControl( self, control ):
self.feilds.append( [ control.getName(), control ] )
+ def validate( self, request ):
+
+ if not self.passback: self.parseForm( request )
+
+ check = True
+
+ previous_values = ssxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference
+ if DEBUG: print previous_values
+
+ for (feild, control) in self.feilds:
+ if not control.validate( previous_values.get( feild ) ):
+ check = False
+ if DEBUG: print "> %s = %s" % (feild, previous_values.get( feild ))
+
+ return check
+
class SheetControl( HTMLBase ):
- def __init__( self ):
+ def __init__( self, reg_exp = ".*" ):
HTMLBase.__init__( self )
self.name = ""
+ self.reg_exp = reg_exp
def write_Control( self, request, persistedValue ):
request.write( "<tr colspan='2'><td>%s</td></tr>" % persistedValue )
- def validate( self ):
- return True
+ def write_Help( self, request ):
+ request.write( "<tr><td align='right' colspan='2'><p class='small'>Text must match pattern:" )
+ request.write( " %s</p></td></tr>" % self.reg_exp )
+ def validate( self, persistedValue ):
+ if persistedValue is None:
+ persistedValue = ""
+
+ return not re.compile( self.reg_exp ).match( persistedValue ) is None
+
def getName( self ):
return self.name
class InputControl( SheetControl ):
- def __init__( self, name, defaultValue, humanText):
- SheetControl.__init__( self )
+ def __init__( self, name, defaultValue, humanText, reg_exp = ".*", help_text = "You must enter the appropriate details in this feild." ):
+ SheetControl.__init__( self, reg_exp )
self.setName( name )
self.defaultValue = defaultValue
self.humanText = humanText
+ self.help_text = help_text
def write_Control( self, request, persistedValue ):
if persistedValue is None:
persistedValue = self.defaultValue
- request.write( "<tr><td width='50%%'><p>%s</p></td><td width='50%%'><input type='text' name='%s' value=\"%s\"></td></tr>" % (self.humanText, self.getName(), persistedValue) )
+ request.write( "<tr><td width='50%%'><p>%s</p></td><td width='50%%'><input size='40'type='text' name='%s' value=\"%s\"></td></tr>" % (self.humanText, self.getName(), persistedValue) )
+ def write_Help( self, request ):
+ request.write( "<tr><td align='right' colspan='2'><p class='small'>" )
+ request.write( " %s</p></td></tr>" % self.help_text )
+
class TextControl( SheetControl ):
def __init__( self, text ):
def write_Control( self, request, persistedValue ):
request.write( "<tr><td colspan='2'><p class='small'>%s</p></tr></td>" % self.text )
-
-
+class ListControl( SheetControl ):
+
+ def __init__( self, name, options, humanText ):
+ SheetControl.__init__( self )
+ self.setName( name )
+ self.options = options
+ self.humanText = humanText
+
+ def write_Control( self, request, persistedValue ):
+ request.write( "<tr><td width='50%%'><p>%s</p></td><td width='50%%'>" % self.humanText )
+ request.write( "<select name='%s'>" % self.getName() )
+ for (value, text) in self.options:
+ if value == persistedValue:
+ request.write( "<option value='%s' selected>%s\n" % (value, text) )
+ else:
+ request.write( "<option value='%s'>%s\n" % (value, text) )
+ request.write( "</select></td></tr>" )
+
+ def validate( self, persistedValue ):
+ for (value, text) in self.options:
+ if value == persistedValue:
+ return True
+
+ return False
+
+class FileControl( InputControl ):
+
+ def __init__( self, name, defaultValue, humanText, reg_exp = ".*", help_text = "You must enter the appropriate details in this feild." ):
+ InputControl.__init__( self, name, defaultValue, humanText )
+
+ def validate( self, persistedValue ):
+ if persistedValue is None: return False
+ try:
+ open( persistedValue )
+ return True
+ except IOError, TypeError:
+ return False
+ def write_Help( self, request ):
+ request.write( "<tr><td colspan='2' align='right'><p class='small'>File does not exist: you must enter a valid, absolute file path.</p></td></tr>" )
+
+class TickControl( SheetControl ):
+
+ def __init__( self, name, defaultValue, humanText ):
+ SheetControl.__init__( self )
+ self.setName( name )
+ self.defaultValue = defaultValue
+ self.humanText = humanText
+
+ def write_Control( self, request, persistedValue ):
+ request.write( "<tr><td width='50%%'><p>%s</p></td><td width='50%%'>" % self.humanText )
+
+ if persistedValue == 'True':
+ request.write( "<input type='checkbox' name='%s' value='True' checked>" % self.getName() )
+ else:
+ request.write( "<input type='checkbox' name='%s' value='True'>" % self.getName() )
+
+ request.write( "</select></td></tr>" )
+